// export type SearchInputProps = {
//     placeholder?: string;
//     enterButton?: string;
//     size?: number;
//     // tableProps? any;
//     onSearch?: (values: any) => void;
// };

import { PaginationProps } from '@douyinfe/semi-ui/lib/es/pagination';
import { SearchResult, IdValue, OptionProps } from '@ugeez/frontend-commons/lib/types';
import { action, observable, toJS } from 'mobx';

export type SearchFilter = {
    keyword?: string | null;
} & Record<string, any>;

const defaultPageSize = 20;

export class SearchTablePageStore<T extends IdValue> {
    @observable
    data: T[] = [];

    @observable
    pageSize = defaultPageSize;

    @observable
    page = 1;

    @observable
    total = 0;

    @observable
    filter: any = {};

    @observable
    selectedKeys: any[] = [];

    @observable
    selecteds: T[] = [];

    @observable
    selected: T | undefined = undefined;

    @action
    select(selectedKeys: any[], selecteds: T[]): void {
        this.selectedKeys = selectedKeys;
        this.selecteds = selecteds;
    }

    @action
    clearSelection(): void {
        this.selectedKeys = [];
        this.selecteds = [];
    }

    clear(): void {
        this.selectedKeys = [];
        this.selecteds = [];
        this.filter = {};
        this.total = 0;
        this.page = 1;
        this.pageSize = defaultPageSize;
        this.data = [];
    }

    get hasMultipleSelected(): boolean {
        return !!this.selecteds && this.selecteds.length > 0;
    }

    get hasSelected(): boolean {
        return !!this.selected;
    }

    @action
    async search(filter: SearchFilter, page: number, pageSize: number): Promise<SearchResult<T>> {
        this.clearSelection();

        filter = { ...toJS(this.filter), ...toJS(filter) };
        const result = await this.doSearch(filter, page, pageSize);

        this.filter = filter;
        this.page = result.page;
        this.pageSize = result.pageSize;
        this.total = result.total;
        this.data = result.list;

        return result;
    }

    protected doSearch(filter: SearchFilter, page: number, pageSize: number): Promise<SearchResult<T>> {
        throw new Error(`doSearch(${filter}, ${page}, ${pageSize}) method should be overrided.`);
    }

    @action
    refresh(): Promise<SearchResult<T>> {
        return this.search(this.filter, this.page, this.pageSize);
    }
}

export type SearchTablePageProps<T extends IdValue> = React.PropsWithChildren<any> & {
    className?: string;
    store: SearchTablePageStore<T>;
    columns: any[];
    dataItemKey?: string;
    pagination?: PaginationProps;
    formSchema: SearchFormSchema;
    selectable?: boolean;
    onRowSelectionChange?: ((selectedKeys: string[], selectedItems: T[]) => void) | null;
    onSearch?: (result: SearchResult<T>) => void | Promise<void> | Promise<any>;
    onError?: (err: Error | string) => void | Promise<void> | Promise<any>;
};

export enum SearchFormControlType {
    Input = 'input',
    Select = 'select',
    Date = 'date',
    Button = 'button',
    RadioGroup = 'radioGroup'
}

export enum SearchFormControlAction {
    Search = 'search',
    Clear = 'clear'
}

export type SearchFormSchemaControl = {
    view?: SearchFormControlType | React.ReactNode;
    size?: number;
    placeholder?: string;
    label?: string;
    defaultValue?: string | number | unknown;
    name?: string;
    action?: SearchFormControlAction;
    props?: any;
    disabled?: boolean;
};

export type SearchFormSchemaButtonControl = {
    text: string;
    type?: 'default' | 'primary' | 'danger';
    onClick?: () => void;
} & SearchFormSchemaControl;

export type SearchFormSchemaContainer = {
    views?: SearchFormControlElement[];
    align?: 'left' | 'center' | 'right';
} & SearchFormSchemaControl;

export type SearchFormSchemaRadioGroupControl = {
    radioItems?: (OptionProps | string)[];
    onClick?: () => void;
    submitWhenChange?: boolean;
} & SearchFormSchemaControl;

export type SearchFormSchemaSelectControl = {
    options?: OptionProps[];
    onChange?: (value) => void;
    submitWhenChange?: boolean;
} & SearchFormSchemaControl;

export type SearchFormSchema<T = undefined> = {
    rows: SearchFormElement[][];
    defaultFormData?: T;
};

export type SearchFormControlElement =
    | SearchFormSchemaControl
    | SearchFormSchemaButtonControl
    | SearchFormSchemaRadioGroupControl
    | SearchFormSchemaSelectControl;

export type SearchFormElement = SearchFormControlElement | SearchFormSchemaContainer;
